class Building:
    """建筑类，包含建筑名称和位置属性"""

    def __init__(self, name, location):
        self.name = name  # 建筑名称
        self.location = location  # 建筑位置

    def __str__(self):
        return f"Building(name='{self.name}', location='{self.location}')"


class Course:
    """课程类，受约束：必须关联某个Building"""

    def __init__(self, name, code, building):
        # 约束：Course必须关联一个Building对象
        if not isinstance(building, Building):
            raise ValueError("Course must be associated with a Building instance!")

        self.name = name  # 课程名称
        self.code = code  # 课程代码
        self.building = building  # 授课建筑（组合关系的一部分）

    def __str__(self):
        return f"Course(name='{self.name}', code='{self.code}', building={self.building})"


class College:
    """学院类，包含：
    - 聚合关系：包含Building对象（建筑可独立存在）
    - 组合关系：包含Course对象（课程依赖学院存在）
    """

    def __init__(self, name):
        self.name = name
        self.buildings = []  # 聚合：Building对象列表（建筑可独立于学院）
        self.courses = []  # 组合：Course对象列表（课程属于学院）

    # 聚合关系：添加建筑（建筑可独立存在）
    def add_building(self, building):
        if isinstance(building, Building):
            self.buildings.append(building)
        else:
            raise ValueError("Only Building instances can be added!")

    # 组合关系：添加课程（课程依赖学院，且必须关联建筑）
    def add_course(self, course):
        if isinstance(course, Course):
            self.courses.append(course)
        else:
            raise ValueError("Only Course instances can be added!")

    # 显示学院信息
    def show_info(self):
        print(f"College: {self.name}")
        print("\nBuildings:")
        for b in self.buildings:
            print(f"  - {b}")
        print("\nCourses:")
        for c in self.courses:
            print(f"  - {c}")


# 测试代码
if __name__ == "__main__":
    # 创建建筑（可独立存在）
    building1 = Building("Main Building", "Central Campus")
    building2 = Building("Science Hall", "North Campus")

    # 创建学院（聚合建筑）
    college = College("Computer Science College")
    college.add_building(building1)
    college.add_building(building2)

    # 创建课程（必须关联建筑，且属于学院）
    course1 = Course("Python Programming", "CS101", building1)
    course2 = Course("Data Structures", "CS201", building2)
    college.add_course(course1)
    college.add_course(course2)

    # 尝试创建不关联建筑的课程（触发约束）
    try:
        invalid_course = Course("Math", "MATH101", "No Building")
    except ValueError as e:
        print(f"Error: {e}\n")

    # 显示学院信息
    college.show_info()